package com.ruoyi.zsyh.controller.applet.user;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.wx.WXPayConfig;
import com.ruoyi.common.utils.wx.WXPayRequest;
import com.ruoyi.common.utils.wx.WxAccessToken;
import com.ruoyi.common.utils.wx.WxAccessTokenUtils;
import com.ruoyi.zsyh.domain.*;
import com.ruoyi.zsyh.service.*;
import net.sf.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/**
 * @author yuexl
 */
@Controller
@RequestMapping("/applet/zsyh/wxStore")
public class WxStoreOrderController {

    private Logger logger = LoggerFactory.getLogger(WxStoreOrderController.class);

    //小程序的appId
    @Value("${wxconfig.appIdAppletUser}")
    private String appIdApplet;
    //小程序的appSecret
    @Value("${wxconfig.appSecretAppletUser}")
    private String appSecretApplet;

    @Value("${wxconfig.partner}")
    private String partner;

    @Value("${wxconfig.partnerKey}")
    private String partnerKey;

    @Value("${wxconfig.repairNotifyStoreOrderMoney}")
    private String repairNotifyStoreOrderMoney;


    @Autowired
    private ServerConfig serverConfig;

    @Resource
    private WXPayConfig wxPayConfig;

    @Autowired
    private IZsyhPlatformUserService zsyhPlatformUserService;

    @Autowired
    private IZsyhStoreOrderService zsyhStoreOrderService;


    /**
     * 支付商城订单
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping(value = "/wxPayStoreOrderMoney")
    public AjaxResult wxPayStoreOrderMoney(String userId, String orderId, HttpServletResponse response, HttpServletRequest request) throws IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        ZsyhStoreOrder order = zsyhStoreOrderService.selectZsyhStoreOrderById(orderId);
        ZsyhPlatformUser user = zsyhPlatformUserService.selectZsyhPlatformUserById(userId);
        String openId = user.getUserOpenid();
        //更改钱数
//        String totalfee = order.getOrderMoney().toString();
        String totalfee = "0.01";
        List<Map<String, Object>> commlist = new ArrayList<Map<String, Object>>();
        Map<String, Object> resultmap = new HashMap<String, Object>();
        //微信支付jsApi
        logger.info(openId);
        WxPayDto tpWxPay = new WxPayDto();
        tpWxPay.setOpenId(openId);
        tpWxPay.setBody("商品金额");
        tpWxPay.setOrderId(orderId);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(totalfee);
        tpWxPay.setAttach(orderId);

        String returnresult = getPackageApplets(tpWxPay);
        logger.info(returnresult);
        String[] resultarray = returnresult.split(",");
        for (String item : resultarray) {
            String[] temp = item.split(":");
            logger.info("item" + item);
            logger.info("temp[0]" + temp[0] + "temp[1]" + temp[1]);
            temp[0] = temp[0].replaceAll("\"", "");
            temp[1] = temp[1].replaceAll("\"", "");
            resultmap.put(temp[0], temp[1]);
        }
        commlist.add(resultmap);
        JSONArray json = JSONArray.fromObject(commlist);
        response.reset();
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        ServletOutputStream out = response.getOutputStream();
        //out.print(callback + "(" + json + ")");

        logger.info("json**********" + json + "***************");
//        logger.info("callback"+callback+"*********************after");
        return AjaxResult.success(json);
    }


    /**
     * 小程序支付回调  商品订单
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/repairNotifyStoreOrderMoney", method = RequestMethod.POST)
    @ResponseBody
    public String repairNotifyStoreOrderMoney(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        WXPayRequest wxPayRequest = new WXPayRequest(this.wxPayConfig);
        Map<String, String> result = new HashMap<String, String>();
        Map<String, String> params = null;
        String returnxml = "";
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        //以字节流的形式读取request中的数据
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        params = WXPayUtil.xmlToMap(sb.toString());
        logger.info("1.notify-params>>>>>>>>>>>:" + params);

        String returnCode = params.get("return_code");
        logger.info("3.returnCode:" + returnCode);
        if (returnCode.equals("SUCCESS")) {
            //判断签名是否正确
            boolean flag = wxPayRequest.isResponseSignatureValid(params, partnerKey);
            logger.info("2.notify-flag:" + flag);
            if (flag) {
                //获取微信订单号
                String transactionId = params.get("transaction_id");
                //获取商户订单号
                String outTradeNo = params.get("out_trade_no");

                String total_fee = params.get("total_fee");//支付金额

                //附加信息原路返回 订单id
                String attach = params.get("attach");

                logger.info("transactionId====================================" + transactionId);
                logger.info("outTradeNo====================================" + outTradeNo);
                logger.info("attach====================================" + attach);
                logger.info("total_fee====================================" + total_fee);
                logger.info("outTradeNo====================================" + outTradeNo);

                //修改订单支付状态
                //状态（1待付款 2待发货 3已发货 4已收货 0已取消）
                ZsyhStoreOrder order = new ZsyhStoreOrder();
                order.setId(outTradeNo);
                order.setTransactionId(transactionId);
                order.setOrderState("2");
                order.setPaymentTime(new Date());
                zsyhStoreOrderService.updateZsyhStoreOrderApplet(order);

                result.put("return_code", "SUCCESS");
                result.put("return_msg", "支付成功");
                logger.info("4.订单：" + outTradeNo + " 交易完成" + ">>>" + transactionId);
            } else {
                result.put("return_code", "FAIL");
                result.put("return_msg", "签名失败");
                logger.info("签名验证失败>>>>>>>>>>>>");
            }
        } else {
            result.put("return_code", "FAIL");
            result.put("return_msg", "支付失败");
            logger.info("");
        }


        returnxml = WXPayUtil.mapToXml(result);
        return returnxml;
    }



    /**
     * 获取请求预支付id报文
     * 商城下订单
     * @return
     */
    @SuppressWarnings("static-access")
    public String getPackageApplets(WxPayDto tpWxPayDto) {

        String openId = tpWxPayDto.getOpenId();
        // 1 参数
        // 订单号
        String orderId = tpWxPayDto.getOrderId();
        // 附加数据 原样返回
        String attach = tpWxPayDto.getAttach();
        // 总金额以分为单位，不带小数点
        String totalFee = StringUtils.getMoney(tpWxPayDto.getTotalFee());

        // 订单生成的机器 IP
        String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
//        String notify_url = "https://www.zzzsyh.com/cs_pay/wxpay/notify";
        String trade_type = "JSAPI";

        // ---必须参数
        // 商户号
        String mch_id = partner;
        // 随机字符串
        String nonce_str = StringUtils.getNonceStr();

        // 商品描述根据情况修改
        String body = tpWxPayDto.getBody();

        // 商户订单号
        String out_trade_no = orderId;

        SortedMap<String, String> packageParams = new TreeMap<String, String>();
        packageParams.put("appid", appIdApplet);
        packageParams.put("attach", attach);
        packageParams.put("body", body);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);

        packageParams.put("notify_url", repairNotifyStoreOrderMoney);
        packageParams.put("openid", openId);
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("total_fee", totalFee);
        packageParams.put("trade_type", trade_type);


        RequestHandler reqHandler = new RequestHandler(null, null);
        reqHandler.init(appIdApplet, appSecretApplet, partnerKey);

        String sign = reqHandler.createSign(packageParams);
        logger.info("第一次签名------------------------------" + sign);
        String xml = "<xml>" + "<appid>" + appIdApplet + "</appid>" + "<mch_id>"
                + mch_id + "</mch_id>" + "<nonce_str>" + nonce_str
                + "</nonce_str>" + "<sign>" + sign + "</sign>"
                + "<body><![CDATA[" + body + "]]></body>"
                + "<out_trade_no>" + out_trade_no
                + "</out_trade_no>" + "<attach>" + attach + "</attach>"
                + "<total_fee>" + totalFee + "</total_fee>"
                + "<spbill_create_ip>" + spbill_create_ip
                + "</spbill_create_ip>" + "<notify_url>" + repairNotifyStoreOrderMoney
                + "</notify_url>" + "<trade_type>" + trade_type
                + "</trade_type>" + "<openid>" + openId + "</openid>"
                + "</xml>";
        String prepay_id = "";
        String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";


        prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);

        logger.info("获取到的预支付ID：" + prepay_id);


        //获取prepay_id后，拼接最后请求支付所需要的package

        SortedMap<String, String> finalpackage = new TreeMap<String, String>();
        String timestamp = Sha1Util.getTimeStamp();
        String packages = "prepay_id=" + prepay_id;
        finalpackage.put("appId", appIdApplet);
        finalpackage.put("timeStamp", timestamp);
        finalpackage.put("nonceStr", nonce_str);
        finalpackage.put("package", packages);
        finalpackage.put("signType", "MD5");
        //要签名
        String finalsign = reqHandler.createSign(finalpackage);
        logger.info("第二次签名------------------------------" + finalsign);
        String finaPackage = "\"appId\":\"" + appIdApplet + "\",\"timeStamp\":\"" + timestamp
                + "\",\"nonceStr\":\"" + nonce_str + "\",\"package\":\""
                + packages + "\",\"signType\" : \"MD5" + "\",\"paySign\":\""
                + finalsign + "\"";

        logger.info("V3 jsApi package:" + finaPackage);
        return finaPackage;
    }

    /**
     * 小程序获取openId 和 session_key
     * 用户授权获取手机号
     * https://api.weixin.qq.com/sns/jscode2session?appid=wxc2298573abab5690&secret=2668443994e3d65e93df98223533cf2d&js_code=021UM4ll220fM64hfrll27c8C62UM4lB&grant_type=authorization_code
     */
    @RequestMapping(value = "/wechat/test")
    @ResponseBody
    public AjaxResult test()throws Exception {
//        //封装参数
        String scene = "888888";//带参
        String img = postPromotionCode(scene);
        System.out.println(img);
        return AjaxResult.success(img);
//        return AjaxResult.success("操作成功", updateStoreWxImage());
    }

    /**
     * 生成带参小程序二维码 -- 用户推广码
     * @param scene	要输入的内容
     */
    public String postPromotionCode(String scene) {
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appIdApplet+"&secret="+appSecretApplet;
        String json = UrlUtils.loadURL(tokenUrl);
        Map<String, Object> wechatToken = JSON.parseObject(json, Map.class);
        String access_token = String.valueOf(wechatToken.get("access_token"));
        logger.info("access_token-----------------------" + access_token);

        String imgName = scene + ".png";
        String imgUrl = serverConfig.getUrl() + "/profile/upload/store/promotionCode/" +  imgName;
        try{
            URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token);
//            URL url = new URL("https://api.weixin.qq.com/wxa/getwxacode?access_token="+access_token);//少量的
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
            // conn.setReadTimeout(2000);//读取超时 单位毫秒
            // 发送POST请求必须设置如下两行
            httpURLConnection.setDoOutput(true); // 打开写入属性
            httpURLConnection.setDoInput(true); // 打开读取属性
            httpURLConnection.setRequestMethod("POST");// 提交方式
            // 不得不说一下这个提交方式转换！！真的坑。。改了好长时间！！一定要记得加响应头
            httpURLConnection.setRequestProperty("Content-Type", "application/x-javascript; charset=UTF-8");// 设置响应头
            // 获取URLConnection对象对应的输出流
            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
//            Map map = new HashMap();
//            map.put("r", 255);
//            map.put("g", 246);
//            map.put("b", 229);
            String page = "pages/product/index/index";
            // 发送请求参数
            JSONObject paramJson = new JSONObject();
            paramJson.put("scene", scene); // 你要放的内容
            paramJson.put("page", page);
            paramJson.put("env_version", "develop"); // 要打开的小程序版本。正式版为 release，体验版为 trial，开发版为 develop
//            paramJson.put("path", "pages/shopNear/detail/detail1?id=1026558882538852352");
            paramJson.put("width", 430); // 宽度
            paramJson.put("auto_color", true);
            paramJson.put("is_hyaline", false);
//            paramJson.put("line_color", map);
            printWriter.write(paramJson.toString());
            // flush输出流的缓冲
            printWriter.flush();
            BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();

            // 如果没有该路径，那么创建一个
            File file = new File(filePath + "/store/promotionCode");
            if (!file.exists()){
                file.mkdirs();
            }
            //创建一个空文件
            OutputStream os = new FileOutputStream(new File(filePath + "/store/promotionCode/" + imgName));
            //ByteArrayOutputStream os = new ByteArrayOutputStream();
            int len;
            byte[] arr = new byte[1024];
            while ((len = bis.read(arr)) != -1)
            {
                os.write(arr, 0, len);
                os.flush();
            }
            os.close();
            // 上传云储存
            //InputStream is = new ByteArrayInputStream(os.toByteArray());
            //retMap = UploadUtils.upload(is);

//            File file1 = new File(filePath + imgName);
//            imgBase64 = Base64.getEncoder().encodeToString(fileToByte(file1));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return imgUrl;
    }

}
